package org.dfl.plugin.views.actions;

import java.io.File;
import java.util.Collection;

import org.dfl.core.data.History;
import org.dfl.core.data.IODataManager;
import org.dfl.core.data.Token;
import org.dfl.core.data.types.Type;
import org.dfl.core.model.Place;
import org.dfl.messages.Messages;
import org.dfl.plugin.DflPlugin;
import org.dfl.plugin.ProjectConstraints;
import org.dfl.plugin.dialogs.DialogsManager;
import org.dfl.plugin.utils.WorkbenchUtil;
import org.dfl.plugin.views.debug.HistoriesTreeView;
import org.dfl.plugin.views.debug.TokensTreeView;
import org.dfl.plugin.views.debug.model.HistoryTreeElem;
import org.dfl.plugin.views.debug.model.TokenTreeElem;
import org.dfl.plugin.views.debug.model.TokensTreeViewRoot;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.action.IAction;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.actions.ActionDelegate;

/**
 * action that provide loading token objects. History saved in a loading file
 * are not used. It's used in a TokensTreeView (see mapping in plugin.xml file)
 * 
 * @author Piotr Wlodarczyk
 * 
 */
public class LoadTokensAction extends ActionDelegate implements
		IViewActionDelegate {
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.actions.ActionDelegate#run(org.eclipse.jface.action.IAction)
	 */
	public void run(IAction action) {
		if (view != null && view.getCommonViewer().getInput() != null
				&& !view.getHistoryTreeElems().isEmpty()) {
			TokensTreeViewRoot root = (TokensTreeViewRoot) view
					.getCommonViewer().getInput();
			Place place = root.getHistoryTreeElems().iterator().next()
					.getPlace();

			Collection<Token> tokens = load(place.getTypeContainer().getType());
			if (tokens == null) {
				return;
			} else if (tokens.isEmpty()) {
				DialogsManager.openErrorDialog(Messages.LoadTokensAction_0);
			}

			if (root.getHistoryTreeElems().size() > 1
					&& !DialogsManager
							.openOkCancelDialog(
									"Confirm",
									"You have selected multiple histories.\n All tokens will be loaded to each of those histories.\n Are you sure to continue?")) {
				return;
			}
			
			HistoriesTreeView historiesTreeView = HistoriesTreeView.getView();
			TokensTreeView tokensTreeView = TokensTreeView.getView();
			// place listeners have to be removed before
			if (historiesTreeView != null)
				historiesTreeView.stopListenPlace();
			if (tokensTreeView != null)
				tokensTreeView.stopListenPlace();

			for (HistoryTreeElem historyTreeElem : root .getHistoryTreeElems()) {
				History history = historyTreeElem.getHistory();
				synchronized (DflPlugin.class) {
					for (Token token : tokens) {
						token.setHistory(history);
						historyTreeElem.getTokens().add(token);
						place.addToken(token);
						root.addChild(new TokenTreeElem(root, token, place));
					}
				}
			}
			// restore place listeners
			if (historiesTreeView != null)
				historiesTreeView.startListenPlace();
			if (tokensTreeView != null)
				tokensTreeView.startListenPlace();

			view.getCommonViewer().refresh();
		}
	}

	TokensTreeView view;

	public void init(IViewPart view) {
		if (view instanceof TokensTreeView)
			this.view = (TokensTreeView) view;
	}

	private Collection<Token> load(Type t) {
		FileDialog dlg = new FileDialog(Display.getCurrent().getActiveShell(),
				SWT.SINGLE);

		IProject project = WorkbenchUtil.getCurrentProject();
		String projectPath = project.getLocation().toFile().getAbsolutePath();
		if (new File(projectPath + ProjectConstraints.PROJECT_DIR_TOKENS)
				.exists()) { //$NON-NLS-1$
			dlg.setFilterPath(projectPath
					+ ProjectConstraints.PROJECT_DIR_TOKENS); //$NON-NLS-1$
		} else {
			dlg.setFilterPath(projectPath);
		}

		// Change the title bar text
		dlg.setText(Messages.LoadTokensAction_1);

		// null if user cancels
		String fileName = dlg.open();
		if (fileName != null) {
			try {
				return IODataManager.loadFlatTokens(fileName, t);
			} catch (Exception e) {
				DialogsManager.openErrorDialog(e);
			}
		}
		return null;
	}
}
